package site.zhanjingbo.shop.web.filter;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import site.zhanjingbo.shop.meta.User;
import site.zhanjingbo.shop.utils.Permission;
import site.zhanjingbo.shop.utils.PermissionType;
import site.zhanjingbo.shop.utils.ResponseType;

public class SecurityInterceptor extends HandlerInterceptorAdapter {

	// 默认的接受的 RoleType, 仅作用于没有使用注解标记的方法。
	private PermissionType[] defaultAllowedRoleType = { PermissionType.NOLOGIN };

	// 默认的ResponseType, 仅作用于没有使用注解标记的方法。
	private ResponseType defaultResponseType = ResponseType.PAGE;

	// 需要登录时的重定向地址。仅在返回方式为 PAGE 时生效。
	private String redirectPath = "/login";

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Permission permission = handlerMethod.getMethodAnnotation(Permission.class);
		PermissionType[] allowedPermissionType = defaultAllowedRoleType;
		ResponseType responseType = defaultResponseType;

		if (permission != null) {
			allowedPermissionType = permission.permission();
			responseType = permission.response();
		}

		if (validate(allowedPermissionType, -1)) {
			return true;
		}

		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		if (user != null && validate(allowedPermissionType, user.getUserType())) {
			return true;
		}

		if (responseType == ResponseType.PAGE) {
			response.sendRedirect(redirectPath);
		} else {
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html;charset=UTF-8");
			response.setStatus(403);
			OutputStream outputStream = response.getOutputStream();
			PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(outputStream, "utf-8"));
			printWriter.println("{\"result\":false,\"code\":403,\"message\":\"Permission Denied.\"}");
			printWriter.flush();
			printWriter.close();
		}

		return false;
	}

	private boolean validate(PermissionType[] allowedPermissionType, int currentPermissionType) {
		if (allowedPermissionType == null)
			return false;
		for (PermissionType role : allowedPermissionType) {
			if (role.getValue() == currentPermissionType) {
				return true;
			}
		}
		return false;
	}

}
